"""
交易所抽象基类

定义统一的交易所接口，屏蔽不同交易所API差异
"""

from abc import ABC, abstractmethod
from typing import Dict, List, Any, Optional, Tuple
from datetime import datetime
import logging
from ..core.exceptions import ExchangeAPIError, ValidationError


class BaseExchange(ABC):
    """交易所抽象基类"""
    
    def __init__(self, config: Dict[str, Any]):
        """
        初始化交易所适配器
        
        Args:
            config: 交易所配置
        """
        self.config = config
        self.name = config.get('name', 'unknown')
        self.logger = logging.getLogger(f'exchange_{self.name}')
        
        # API配置
        self.api_key = config.get('api_key', '')
        self.secret_key = config.get('secret_key', '')
        self.passphrase = config.get('passphrase', '')
        self.testnet = config.get('testnet', True)
        self.sandbox = config.get('sandbox', True)
        
        # 功能配置
        self.enabled = config.get('enabled', False)
        self.supported_types = config.get('supported_types', ['spot'])
        
        # 费率配置
        self.fees = config.get('fees', {
            'spot': {'maker': 0.001, 'taker': 0.001},
            'futures': {'maker': 0.0002, 'taker': 0.0005}
        })
        
        # 连接状态
        self.connected = False
        self.last_heartbeat = None
        
    @abstractmethod
    def get_spot_balance(self) -> Dict[str, Any]:
        """
        获取现货账户余额
        
        Returns:
            账户余额信息
        """
        pass
    
    @abstractmethod
    def spot_place_order(self, symbol: str, order_type: str, side: str, 
                        amount: float, price: Optional[float] = None) -> Dict[str, Any]:
        """
        现货下单
        
        Args:
            symbol: 交易对
            order_type: 订单类型 (limit/market)
            side: 买卖方向 (buy/sell)
            amount: 数量
            price: 价格 (限价单必需)
            
        Returns:
            订单信息
        """
        pass
    
    @abstractmethod
    def get_futures_balance(self) -> Dict[str, Any]:
        """
        获取合约账户余额
        
        Returns:
            账户余额信息
        """
        pass
    
    @abstractmethod
    def get_futures_position(self, symbol: Optional[str] = None) -> Dict[str, Any]:
        """
        获取合约仓位
        
        Args:
            symbol: 交易对，为None时获取所有仓位
            
        Returns:
            仓位信息
        """
        pass
    
    @abstractmethod
    def futures_place_order(self, symbol: str, order_type: str, side: str, 
                           amount: float, leverage: int, 
                           price: Optional[float] = None) -> Dict[str, Any]:
        """
        合约下单
        
        Args:
            symbol: 交易对
            order_type: 订单类型 (limit/market)
            side: 买卖方向 (buy/sell)
            amount: 数量
            leverage: 杠杆倍数
            price: 价格 (限价单必需)
            
        Returns:
            订单信息
        """
        pass
    
    @abstractmethod
    def get_kline(self, symbol: str, period: str, limit: int = 100) -> List[Dict[str, Any]]:
        """
        获取K线数据
        
        Args:
            symbol: 交易对
            period: 时间周期
            limit: 数据条数
            
        Returns:
            K线数据列表
        """
        pass
    
    @abstractmethod
    def get_latest_price(self, symbol: str) -> float:
        """
        获取最新价格
        
        Args:
            symbol: 交易对
            
        Returns:
            最新价格
        """
        pass
    
    @abstractmethod
    def cancel_order(self, order_id: str, symbol: str) -> Dict[str, Any]:
        """
        撤销订单
        
        Args:
            order_id: 订单ID
            symbol: 交易对
            
        Returns:
            撤销结果
        """
        pass
    
    @abstractmethod
    def get_order_status(self, order_id: str, symbol: str) -> Dict[str, Any]:
        """
        获取订单状态
        
        Args:
            order_id: 订单ID
            symbol: 交易对
            
        Returns:
            订单状态信息
        """
        pass
    
    def validate_symbol(self, symbol: str) -> bool:
        """
        验证交易对格式
        
        Args:
            symbol: 交易对
            
        Returns:
            是否有效
        """
        if not symbol or '-' not in symbol:
            return False
        
        parts = symbol.split('-')
        return len(parts) == 2 and all(part.isalpha() for part in parts)
    
    def validate_order_params(self, symbol: str, order_type: str, side: str, 
                             amount: float, price: Optional[float] = None) -> bool:
        """
        验证订单参数
        
        Args:
            symbol: 交易对
            order_type: 订单类型
            side: 买卖方向
            amount: 数量
            price: 价格
            
        Returns:
            是否有效
        """
        # 验证交易对
        if not self.validate_symbol(symbol):
            return False
        
        # 验证订单类型
        if order_type not in ['limit', 'market']:
            return False
        
        # 验证买卖方向
        if side not in ['buy', 'sell']:
            return False
        
        # 验证数量
        if amount <= 0:
            return False
        
        # 限价单必须有价格
        if order_type == 'limit' and (price is None or price <= 0):
            return False
        
        return True
    
    def format_symbol(self, symbol: str) -> str:
        """
        格式化交易对符号
        
        Args:
            symbol: 原始交易对
            
        Returns:
            格式化后的交易对
        """
        # 默认实现，子类可以重写
        return symbol.upper()
    
    def handle_api_error(self, error: Exception, operation: str) -> None:
        """
        处理API错误
        
        Args:
            error: 异常对象
            operation: 操作名称
        """
        error_msg = f"{operation} 失败: {str(error)}"
        self.logger.error(error_msg)
        raise ExchangeAPIError(error_msg, exchange=self.__class__.__name__)
    
    def log_order(self, order_info: Dict[str, Any], action: str = 'SUBMIT') -> None:
        """
        记录订单日志
        
        Args:
            order_info: 订单信息
            action: 操作类型
        """
        self.logger.info(f"{action} 订单: {order_info}")